//
//  WWNotificationCenter.m
//  通知学习
//
//  Created by slience on 2019/10/14.
//  Copyright © 2019 shehuiren. All rights reserved.
//

#import "WWNotificationCenter.h"

@interface WWNotificationCenter()

@property (nonatomic,strong)NSMutableDictionary * obsetvers;

@end

@implementation WWNotificationCenter

+(WWNotificationCenter *)defaultCenter{
    
    static WWNotificationCenter * singleTon;
    
    static dispatch_once_t onceToken ;
    
    dispatch_once(&onceToken, ^{
        
        singleTon = [[self alloc]initSingleton];
    });
    
    return singleTon;
}
-(instancetype)initSingleton{
    
    if ([super init]){
        
        _obsetvers = [[NSMutableDictionary alloc]init];
    }
    
    return self;
}

-(void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable)anObject{
    
    if ([self.obsetvers objectForKey:aName]){//名字为aName通知是否添加过观察者
        
        NSMutableArray *arrays =(NSMutableArray*)[self.obsetvers objectForKey:aName];
        
        //创建数组模型
        
        WWObserverModel *observerModel =[[WWObserverModel alloc]init];
        
        observerModel.observer = observer;
        
        observerModel.selector = aSelector;
        
        observerModel.notifiaionName = aName;
        
        observerModel.objcet = anObject;
        
          NSOperationQueue *queue = [[NSOperationQueue alloc]init];
              queue.maxConcurrentOperationCount = 2;
              observerModel.operationQueue = queue;
        
        __block id  _observe = observer;
        observerModel.block = ^(WWNotification * noti) {
#pragma clang diagnostic push
                        
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [_observe performSelector:aSelector withObject:anObject];
#pragma clang diagnostic pop

        };
        
        [arrays addObject:observerModel];
        
    }else{
        
        NSMutableArray *arrays =[[NSMutableArray alloc]init];
        
        //创建数组模型
        
        WWObserverModel *observerModel =[[WWObserverModel alloc]init];
        
        observerModel.observer = observer;
        
        observerModel.selector = aSelector;
        
        observerModel.notifiaionName = aName;
        
        observerModel.objcet = anObject;
        
        //有两种不通类型的队列:主队列和自定义队列。主队列在主线程上运行，而自定义队列在后台执行。
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//        设置NSOperationQueue的最大并发操作数(maxConcurrentOperationCount)来控制任务执行是并发还是串行。
        queue.maxConcurrentOperationCount = 2;
        observerModel.operationQueue = queue;

         __block id  _observe = observer;
                observerModel.block = ^(WWNotification * noti) {
        #pragma clang diagnostic push
                                
        #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                    [_observe performSelector:aSelector withObject:anObject];
        #pragma clang diagnostic pop

                };
        [arrays addObject:observerModel];
        
        //填充进入数组
        [self.obsetvers setObject:arrays forKey:aName];
    }
}

-(void)postNotification:(WWNotification *)notification{
    
    //name取出来对应观察者数组，执行任务
    
    NSMutableArray *arrays =(NSMutableArray*)[self.obsetvers objectForKey:notification.name];
    
    [arrays enumerateObjectsUsingBlock:^(id  _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){
        
        //取出数据模型
        
        WWObserverModel *observerModel = obj;
        
        id observer = observerModel.observer;
        
        SEL secector = observerModel.selector;
        
        if(!observerModel.operationQueue){
            
#pragma clang diagnostic push
            
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            
            [observer performSelector:secector withObject:notification];
            
#pragma clang diagnostic pop
            
        }else{
            
            //创建任务
            NSBlockOperation *operation =[NSBlockOperation blockOperationWithBlock:^{
                
                //这里用block回调出去
                
                observerModel.block();
                
            }];
            
            
            //如果添加观察者 传入 队列，那么就任务放在队列中执行(子线程异步执行)
            
            NSOperationQueue *operationQueue = observerModel.operationQueue;
            
            [operationQueue addOperation:operation];
            
        }
    }];
    
}

- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject{
    
       NSMutableArray * value = [self.obsetvers objectForKey:aName];
    
    
    [value enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        WWObserverModel * model = obj;
        
        id observer = model.observer;
        
        SEL secector = model.selector;
        
        
        if(!model.operationQueue){
            
#pragma clang diagnostic push
            
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            
            [observer performSelector:secector withObject:anObject];
            
#pragma clang diagnostic pop
            
        }else{
            
            //创建任务
            
            NSBlockOperation *operation =[NSBlockOperation blockOperationWithBlock:^{
                
                //这里用block回调出去
                
                model.block();
                
                NSLog(@"22222222");
                
            }];
            
            //如果添加观察者 传入 队列，那么就任务放在队列中执行(子线程异步执行)
            
            NSOperationQueue *operationQueue = model.operationQueue;
            
            [operationQueue addOperation:operation];
            
        }
        
    }];
}

@end

/*-------------------*/
@implementation WWObserverModel


@end
